package cn.iocoder.yudao.module.system.service.system;


import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.module.system.dal.dataobject.saas.dto.StaffBindDto;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.SystemUserVo;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.system.SystemUsers;
import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMapper;
import cn.iocoder.yudao.module.system.dal.mysql.system.SystemUsersMapper;
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;

/**
 * @author luchunhong
 * @date 2024/10/18/ 17:19
 * @description:
 */
@Service
@DS("master")
public class SystemUserServiceImpl extends ServiceImpl<SystemUsersMapper, SystemUsers> implements ISystemUserService {

    @Resource
    private PermissionService permissionService;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private PasswordEncoder passwordEncoder;

    /**
     * 通过手机号获取用户的信息
     *
     * @param mobile
     * @return
     */

    @Autowired
    private SystemUsersMapper systemUsersMapper;

    @Override
    public SystemUserVo getUserByMobile(String mobile) {
        /**
         * 获取当前登录人的租户编号
         */
        Long tenantId = getLoginUser().getTenantId();
        SystemUserVo userByMobile = systemUsersMapper.getUserByMobile(mobile, tenantId);
        if (userByMobile != null) {
            return userByMobile;
        }
        return null;
    }

    @Override
    public List<SystemUserVo> getUserListByTenantId(Long tenantId, String roleCode) {
        List<SystemUserVo> staffListByTenantId = systemUsersMapper.getStaffListByTenantId(tenantId,roleCode);
        if (ObjectUtils.isEmpty(staffListByTenantId)) {
            return null;
        }
        return staffListByTenantId;
    }


    /**
     * 绑定用户为核销员/操作员/普通用户
     *
     * @param staffBindDto
     * @return
     */
    @Override
    public boolean bindStaff(StaffBindDto staffBindDto) {
        if (!ObjectUtils.isEmpty(staffBindDto.getRoleCodes())) {
            // 使用集合来存储所有查询到的角色ID
            Set<Long> roleIds = staffBindDto.getRoleCodes().stream()
                    .map(roleMapper::selectByCode)  // 查询每个角色名称对应的角色
                    .filter(Objects::nonNull)
                    .map(RoleDO::getId)
                    .collect(Collectors.toSet());
            // 设置角色ID集合到 DTO 中
            staffBindDto.setRoleIds(roleIds);
            permissionService.assignUserRole(staffBindDto.getUserId(), staffBindDto.getRoleIds());
            return true;
        }
        // 若角色名称列表为空，将该用户设置为普通用户
        RoleDO roleDO = roleMapper.selectByCode("common");
        if (roleDO != null) {
            Set<Long> defaultRoleIds = Collections.singleton(roleDO.getId());
            staffBindDto.setRoleIds(defaultRoleIds);
            permissionService.assignUserRole(staffBindDto.getUserId(), defaultRoleIds);
            return true;
        }
        return false;
    }

    @Override
    public Boolean hasSetPassoword() {
        LoginUser loginUser = getLoginUser();
        Long id = loginUser.getId();
        SystemUsers one = lambdaQuery().eq(SystemUsers::getId, id).eq(SystemUsers::getStatus, 0).one();
        String password = one.getPassword();
        if (ObjectUtils.isEmpty(password)){
            throw new RuntimeException("密码未设置");
        }
        return true;
    }

    /**
     * 密码绑定
     * @param map
     * @return
     */
    @Override
    public Boolean bindPassword(Map<String, String> map) {
        String password = map.get("password");
        String passwordAgain = map.get("passwordAgain");
        if (!passwordAgain.equals(password)){
            throw new RuntimeException("两次密码不一致");
        }
        LoginUser loginUser = getLoginUser();
        if (ObjectUtils.isEmpty(loginUser)){
            throw new RuntimeException("用户未登陆");
        }
        boolean update = lambdaUpdate().set(SystemUsers::getPassword, encodePassword(password)).eq(SystemUsers::getId, loginUser.getId()).update();
        if (!update){
            throw new RuntimeException("密码设置失败");
        }
        return true;
    }

    @Override
    public Map<String, Object> getTenantIdByUserName(SystemUsers systemUsers) {
        List<SystemUsers> systemUserList = systemUsersMapper.queryTenantIdByUserNameOrPassword(systemUsers);

        // 用来存储密码匹配的用户
        ArrayList<SystemUsers> passwordEncodeList = new ArrayList<>();
        for (SystemUsers users : systemUserList) {
            // 比对密码是否匹配
            if (passwordEncoder.matches(systemUsers.getPassword(), users.getPassword())) {
                // 如果密码匹配，将该用户加入列表
                passwordEncodeList.add(users);
            }
        }

        // 如果没有匹配的用户，返回空
        if (passwordEncodeList.isEmpty()) {
            throw new RuntimeException("您当前没有权限访问");
        }

        passwordEncodeList.sort(Comparator
                .comparingInt((SystemUsers user) -> getRolePriority(user))  // 角色优先级排序
                .reversed()  // 降序排序（高优先级排前）
                .thenComparing(user -> {
                    // 如果 loginDate 为 null，返回最早的时间（1970年1月1日）
                    Date loginDate = user.getLoginDateS();
                    if (loginDate == null) {
                        return LocalDateTime.MIN; // 默认值：最小的LocalDateTime
                    }
                    // 将 Date 转换为 LocalDateTime
                    LocalDateTime localDateTime = loginDate.toInstant()
                            .atZone(ZoneId.systemDefault())  // 转换为系统默认时区
                            .toLocalDateTime();
                    return localDateTime;
                }, Comparator.reverseOrder())  // 登录时间降序排序（最近的排前）
        );

        // 返回匹配的第一个用户信息
        SystemUsers matchedUser = passwordEncodeList.get(0);
        Map<String, Object> result = new HashMap<>();
        result.put("id", matchedUser.getTenantId());
        result.put("tenantName", matchedUser.getTenantName());
        return  result;
    }






    // 获取角色的优先级，商家管理员 > 超级管理员 > 活动用户
    private int getRolePriority(SystemUsers user) {
        if (user.getRoles().contains("超级管理员")) {
            return 3;  // 商家管理员优先级最高
        } else if (user.getRoles().contains("商家管理员")) {
            return 2;  // 超级管理员优先级次之
        } else if (user.getRoles().contains("活动用户")) {
            return 1;  // 活动用户优先级最低
        }
        return 0;  // 没有角色时返回最低优先级
    }



    /**
     * 对密码进行加密
     *
     * @param password 密码
     * @return 加密后的密码
     */
    private String encodePassword(String password) {
        return passwordEncoder.encode(password);
    }
    }



